from django.http import HttpRequest
from django.core.cache import cache

from rest_framework import status

from jqexception.jqexecption import (
    jq_try,
    UnknowErr,
    RaffleBusyErr,
    RightErr,
    NullErr,
    ReqMethodErr,
)
from wxuser.error import UserIsDisabledErr
from wxuser.models import Users, UserState


class JuqiUser:
    # 临时 用来 统一admin 和 wxuser的 类
    # 后续 应该 采用 ldap 来 统一 所有的用户
    def __init__(self) -> None:
        self.type = None
        self.uuid = None
        self.openid = None
        self.name = None


def flush_admin_cache(token, admin_user):
    cache.set(token, admin_user, 120 * 60)  # 120分钟


def login_auth(func):
    @jq_try
    def check(*args, **kwargs):
        u = JuqiUser()
        request: HttpRequest = None
        if isinstance(args[0], HttpRequest):
            request: HttpRequest = args[0]
        else:
            # used by View class, args[0] is view
            request: HttpRequest = args[1]
        openid = request.META.get("HTTP_X_WX_OPENID", None)

        if openid:
            u.type = "wxuser"
            u.openid = openid
            user = Users.objects.filter(deleted=False).filter(openid=openid).first()
            if user is not None:
                if user.state == UserState.block:
                    raise UserIsDisabledErr
        else:
            token = request.session.get("login_token", None)
            if not token:
                raise RightErr

            admin_user = cache.get(token, {})
            if not admin_user:
                raise RightErr

            flush_admin_cache(token, admin_user)
            u.type = "admin"
            u.uuid = admin_user["uuid"]

        if not u.type:
            raise RightErr

        return func(*args, user_info=u, **kwargs)

    return check


def check_admin(func):
    @login_auth
    def check(*args, **kwargs):
        u = kwargs["user_info"]
        if u.type != "admin":
            raise RightErr
        return func(*args, **kwargs)

    return check
